package com.sunzr0119.conventioncentertemplatebackend.service.impl;

import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.model.GridFSFile;
import com.mongodb.client.gridfs.model.GridFSUploadOptions;
import com.sunzr0119.conventioncentertemplatebackend.dao.NoticeDAO;
import com.sunzr0119.conventioncentertemplatebackend.dto.NoticeDTO;
import com.sunzr0119.conventioncentertemplatebackend.entity.Notice;
import com.sunzr0119.conventioncentertemplatebackend.service.NoticeService;
import lombok.RequiredArgsConstructor;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@RequiredArgsConstructor
public class NoticeServiceImpl implements NoticeService {

    private final GridFSBucket gridFSBucket;
    @Autowired
    private NoticeDAO noticeDAO;

    @Override
    public ResponseEntity<List<Notice>> getNoticeList(){
        List<Notice> noticeList = noticeDAO.findAll();
        if(noticeList.isEmpty()){
            return ResponseEntity.noContent().build();
        }else {
            return ResponseEntity.ok(noticeList);
        }
    }

    @Override
    public ResponseEntity<Notice> getNoticeById(Long id) {
        return null;
    }

    @Override
    public ResponseEntity<String> uploadNotice(MultipartFile file, NoticeDTO noticeDTO) {
        try {
            // 使用 GridFS 存储文件
            GridFSUploadOptions options = new GridFSUploadOptions()
                    .metadata(new org.bson.Document("contentType", file.getContentType()));

            ObjectId gridFsId = gridFSBucket.uploadFromStream(Objects.requireNonNull(file.getOriginalFilename()), file.getInputStream(), options);
            Notice notice = new Notice();

            String id = UUID.randomUUID().toString();

            notice.setId(id);
            notice.setUploaderId(noticeDTO.getUploaderId());
            notice.setSize(file.getSize());
            notice.setTitle(noticeDTO.getTitle());
            notice.setDescription(noticeDTO.getDescription());
            notice.setContentType(file.getContentType());
            notice.setGridFsId(gridFsId.toHexString());
            notice.setFileName(file.getOriginalFilename());
            Date now = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-d-HH:mm");
            notice.setUploadDate(sdf.format(now));

            noticeDAO.save(notice);

            Optional<Notice> res = noticeDAO.findById(notice.getId());
            return res.map(value -> ResponseEntity.ok(value.getTitle())).orElseGet(() -> ResponseEntity.noContent().build());
        }catch (Exception e){
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("文件上传失败"+e.getMessage());
        }

    }

    @Override
    public ResponseEntity<String> deleteNotice(String id) {
        noticeDAO.deleteById(id);
        Optional<Notice> res = noticeDAO.findById(id);
        if (res.isPresent()) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("删除失败！");
        }else {
            return ResponseEntity.ok("删除成功！");
        }
    }

    private String buildContentDisposition(String fileName) {
        try {
            // 使用 UTF-8 编码文件名，以便浏览器能够正确解析中文字符
            String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
            return "attachment; filename=\"" + encodedFileName + "\"; filename*=UTF-8''" + encodedFileName;
        } catch (UnsupportedEncodingException e) {
            // 如果编码失败，使用原始文件名
            return "attachment; filename=\"" + fileName + "\"";
        }
    }

    @Override
    public ResponseEntity<Resource> downloadNotice(String id) {
        Notice notice = noticeDAO.findById(id).orElse(null);
        if(notice == null){
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
        }else {
            ObjectId gridFsId = new ObjectId(notice.getGridFsId());
            GridFSFile gridFSFile = gridFSBucket.find(new org.bson.Document("_id", gridFsId)).first();
            if (gridFSFile == null) {
                return ResponseEntity.notFound().build();
            }
            InputStream inputStream = gridFSBucket.openDownloadStream(gridFsId);
            Resource resource = new InputStreamResource(inputStream);
            // 下载时添加附件头
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_DISPOSITION, buildContentDisposition(notice.getTitle()));
            return ResponseEntity.ok()
                    .headers(headers)
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .body(resource);
        }
    }

}
